package com.aizuda.boot.modules.business.filling.service.impl;

import com.aizuda.boot.modules.business.contract.dto.SingleResponse;
import com.aizuda.boot.modules.business.contract.dto.UserInfo;
import com.aizuda.boot.modules.common.constant.enums.ResponseCodeEnum;
import com.aizuda.boot.modules.business.contract.util.AuthUtil;
import com.aizuda.boot.modules.business.filling.domain.entity.ContractFilingEntity;
import com.aizuda.boot.modules.business.filling.domain.entity.ContractFilingTypeEntity;
import com.aizuda.boot.modules.business.filling.domain.request.PageQuery;
import com.aizuda.boot.modules.business.filling.domain.request.SaveFilingDTO;
import com.aizuda.boot.modules.business.filling.domain.request.UpdateFilingDTO;
import com.aizuda.boot.modules.business.filling.domain.response.FilingShowDTO;
import com.aizuda.boot.modules.business.filling.domain.response.FilingShowListDTO;
import com.aizuda.boot.modules.business.filling.mapper.ContractFilingMapper;
import com.aizuda.boot.modules.business.filling.mapper.ContractFilingTypeMapper;
import com.aizuda.boot.modules.business.filling.service.ContractFilingService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author sangyirong
 * @ClassName ContractFilingServiceImpl
 * @Version 1.0
 * @Date 2025/6/4 16:36
 */
@Service
@Slf4j
public class ContractFilingServiceImpl extends ServiceImpl<ContractFilingMapper, ContractFilingEntity> implements ContractFilingService {

    @Resource
    private ContractFilingMapper contractFilingMapper;

    @Resource
    private ContractFilingTypeMapper contractFilingTypeMapper;

    @Override
    public IPage<FilingShowListDTO> getFilingList(IPage<FilingShowListDTO> page) {
        // 第一步：分页查询主表数据
        IPage<ContractFilingEntity> mainPage = new Page<>(page.getCurrent(), page.getSize());
        IPage<ContractFilingEntity> mainResult = contractFilingMapper.getFilingMainList(mainPage);
        
        // 创建返回结果的分页对象
        IPage<FilingShowListDTO> result = new Page<>(page.getCurrent(), page.getSize(), mainResult.getTotal());
        
        // 如果没有数据，直接返回空结果
        if (CollectionUtils.isEmpty(mainResult.getRecords())) {
            return result;
        }
        
        // 第二步：提取ID列表，查询详细信息（包含聚合数据）
        List<Integer> filingIds = mainResult.getRecords().stream()
                .map(ContractFilingEntity::getId)
                .collect(Collectors.toList());
        
        List<FilingShowListDTO> detailList = contractFilingMapper.getFilingDetailsByIds(filingIds);
        
        // 设置分页结果
        result.setRecords(detailList);
        
        return result;
    }

    /**
     * 创建归档
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<Void> createFiling(SaveFilingDTO dto) {
        try {
            UserInfo currentUser = AuthUtil.getCurrentUser();
            if (Objects.isNull(currentUser.getEmployeeId())){
                return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
            }
            
            // 参数校验
            if (Objects.isNull(dto) || StringUtils.isEmpty(dto.getRuleName()) || 
                CollectionUtils.isEmpty(dto.getContractTypeIds()) || Objects.isNull(dto.getReminderRule())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
            }
            
            long count = contractFilingMapper.selectCount(new LambdaQueryWrapper<ContractFilingEntity>()
                    .eq(ContractFilingEntity::getRuleName, dto.getRuleName()));
            if (count > 0) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "归档名称重复");
            }
            
            // 主表
            ContractFilingEntity contractFilingEntity = new ContractFilingEntity();
            BeanUtils.copyProperties(dto, contractFilingEntity);
            contractFilingEntity.setIsSystem(false);
            contractFilingMapper.insert(contractFilingEntity);

            // 关联表
            saveContractType(contractFilingEntity.getId(), dto.getContractTypeIds());
            
            return SingleResponse.success();
        } catch (Exception e) {
            log.error("创建归档失败", e);
            return SingleResponse.failure(ResponseCodeEnum.ERROR.getCode(), "创建归档失败：" + e.getMessage());
        }
    }

    /**
     * 获取归档
     *
     * @param id
     * @return
     */
    @Override
    public SingleResponse<FilingShowDTO> getFiling(Integer id) {
        try {
            // 参数校验
            if (Objects.isNull(id)){
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
            }
            
            // 主表
            ContractFilingEntity filing = contractFilingMapper.selectById(id);
            if (Objects.isNull(filing)) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), ResponseCodeEnum.DATA_NOT_FOUND.getMsg());
            }
            
            //  关联表
            List<Integer> typeIds = contractFilingTypeMapper.selectList(new LambdaQueryWrapper<ContractFilingTypeEntity>()
                            .eq(ContractFilingTypeEntity::getFilingId, id))
                    .stream().map(ContractFilingTypeEntity::getContractTypeId).collect(Collectors.toList());
            
            // 赋值构造结果
            FilingShowDTO result = new FilingShowDTO();
            BeanUtils.copyProperties(filing, result);
            result.setContractTypeIds(typeIds);
            
            return SingleResponse.of(result);
        } catch (Exception e) {
            log.error("获取归档详情失败，ID: {}", id, e);
            return SingleResponse.failure(ResponseCodeEnum.ERROR.getCode(), "获取归档详情失败：" + e.getMessage());
        }
    }

    /**
     * 更新归档
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<Void> updateFiling(UpdateFilingDTO dto) {
        try {
            UserInfo currentUser = AuthUtil.getCurrentUser();
            if (Objects.isNull(currentUser.getEmployeeId())){
                return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
            }
            
            //  参数校验
            if (Objects.isNull(dto) || Objects.isNull(dto.getId()) || StringUtils.isEmpty(dto.getRuleName()) || 
                CollectionUtils.isEmpty(dto.getContractTypeIds()) || Objects.isNull(dto.getReminderRule())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
            }
            
            ContractFilingEntity filing = contractFilingMapper.selectById(dto.getId());
            if (Objects.isNull(filing)) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), ResponseCodeEnum.DATA_NOT_FOUND.getMsg());
            }
            
            if (filing.getIsSystem()){
                return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "系统归档不允许修改");
            }
            
            long count = contractFilingMapper.selectCount(new LambdaQueryWrapper<ContractFilingEntity>()
                    .ne(ContractFilingEntity::getId, dto.getId())
                    .eq(ContractFilingEntity::getRuleName, dto.getRuleName()));
            if (count > 0) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "归档名称重复");
            }
            
            //  主表
            BeanUtils.copyProperties(dto, filing);
            contractFilingMapper.updateById(filing);
            
            //  关联表
            contractFilingTypeMapper.delete(new LambdaQueryWrapper<ContractFilingTypeEntity>().eq(ContractFilingTypeEntity::getFilingId, filing.getId()));
            saveContractType(filing.getId(), dto.getContractTypeIds());
            
            return SingleResponse.success();
        } catch (Exception e) {
            log.error("更新归档失败", e);
            return SingleResponse.failure(ResponseCodeEnum.ERROR.getCode(), "更新归档失败：" + e.getMessage());
        }
    }

    /**
     * 保存合同类型范围
     *
     * @param id
     * @param contractTypeIds
     */
    private void saveContractType(Integer id, List<Integer> contractTypeIds) {
        List<ContractFilingTypeEntity> filingType = contractTypeIds.stream().map(typeId -> {
            ContractFilingTypeEntity contractFilingType = new ContractFilingTypeEntity();
            contractFilingType.setContractTypeId(typeId);
            contractFilingType.setFilingId(id);
            return contractFilingType;
        }).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(filingType)) {
            for (ContractFilingTypeEntity entity : filingType) {
                contractFilingTypeMapper.insert(entity);
            }
        }
    }

    /**
     * 删除归档
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<Void> deleteFiling(Integer id) {
        try {
            // 参数校验
            if (Objects.isNull(id)) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
            }
            
            ContractFilingEntity filing = contractFilingMapper.selectById(id);
            if (Objects.isNull(filing)) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), ResponseCodeEnum.DATA_NOT_FOUND.getMsg());
            }
            
            if (filing.getIsSystem()){
                return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "系统归档不允许删除");
            }
            
            contractFilingTypeMapper.delete(new LambdaQueryWrapper<ContractFilingTypeEntity>().eq(ContractFilingTypeEntity::getFilingId, id));
            contractFilingMapper.deleteById(id);
            
            return SingleResponse.success();
        } catch (Exception e) {
            log.error("删除归档失败，ID: {}", id, e);
            return SingleResponse.failure(ResponseCodeEnum.ERROR.getCode(), "删除归档失败：" + e.getMessage());
        }
    }

    /**
     * 获取归档列表
     *
     * @return
     */
    @Override
    public SingleResponse<IPage<FilingShowListDTO>> getFilingList(PageQuery pageQuery) {
        try {
            UserInfo currentUser = AuthUtil.getCurrentUser();
            if (Objects.isNull(currentUser.getEmployeeId())){
                return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
            }
            
            // 参数校验
            if (Objects.isNull(pageQuery) || Objects.isNull(pageQuery.getPageNo()) || Objects.isNull(pageQuery.getPageSize())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
            }
            
            IPage<FilingShowListDTO> page = new Page<>(pageQuery.getPageNo(), pageQuery.getPageSize());
            IPage<FilingShowListDTO> result = getFilingList(page);
            
            return SingleResponse.of(result);
        } catch (Exception e) {
            log.error("获取归档列表失败", e);
            return SingleResponse.failure(ResponseCodeEnum.ERROR.getCode(), "获取归档列表失败：" + e.getMessage());
        }
    }
}
